package com.apes.framework.plugin.condition.service;

import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.ApesBean;
import com.apes.framework.plugin.condition.PricingProcedureContext;
import com.apes.framework.plugin.condition.model.ConditionField;
import com.apes.framework.plugin.condition.model.PricingProcedure;
import com.apes.framework.plugin.condition.repository.PricingProcedureRepository;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.JpaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PricingProcedureService extends DomainService {


    @Autowired
    PricingProcedureRepository pricingProcedureRepository;

    @Autowired
    ConditionFieldService conditionFieldService;


    /***
     * 功能： 创建
     * @param request
     * @return
     */
    public PricingProcedure create(SimpleRequest request) {
        PricingProcedure accessSequences = request.getO(PricingProcedure.class);
        return pricingProcedureRepository.saveAndFlush(accessSequences);
    }

    /***
     * 功能： 修改
     * @param request
     * @return
     */
    public PricingProcedure update(SimpleRequest request) {
        checkData(request);
        PricingProcedure accessSequences = request.getO(PricingProcedure.class);
        return pricingProcedureRepository.saveAndFlush(accessSequences);
    }

    /***
     * 功能： 删除
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        checkData(request);
        PricingProcedure conditionField = request.getO(PricingProcedure.class);
        pricingProcedureRepository.delete(conditionField);
        return "删除成功";
    }

    public void checkData(SimpleRequest request) {
        String id = request.get("id");
        PricingProcedure oldConditionField = pricingProcedureRepository.findOne(id);
        if (oldConditionField == null) throw new RuntimeException("定价过程【" + id + "】在系统中不存在。");
    }

    /**
     * 执行定价过程
     */
    public Map process(SimpleRequest request) {
        Map m = request.getMap();
        return pricing(m);
    }

    /**
     * 执行定价过程
     */
    public Map pricing(Map m) {
        String pricingProcedureId = (String) m.get("pricingProcedureId");
        if (StringUtils.isEmpty(pricingProcedureId)) throw new RuntimeException("定价过程编号不允许为空");
        PricingProcedure procedure = pricingProcedureRepository.findOne(pricingProcedureId);
        Map parameters = getParameters(m);
        PricingProcedureContext context = new PricingProcedureContext(parameters);
        procedure.process(context);
        return context.getOut();
    }

    private static List<ConditionField> conditionFields;

    private Map getParameters(Map m) {
        Map parameters = new HashMap();
        if (conditionFields == null) conditionFields = conditionFieldService.findAll();
        m.forEach((k, v) -> {
            parameters.put(k, v);
            if (v instanceof ApesBean) return;
            ConditionField cf = conditionFields.stream().filter(conditionField -> conditionField.getId().equals(k)).findFirst().orElse(null);
            if (cf == null) return;
            Class clazz = cf.fieldClass();
            if (!ApesBean.class.isAssignableFrom(clazz)) return;
            Serializable id;
            if (v instanceof Map) {
                id = (Serializable) ((Map) v).get("id");
            } else if (v instanceof Serializable) {
                id = (Serializable) v;
            } else {
                throw new RuntimeException(String.format("变量：%s 输入错误", k));
            }
            id = JpaUtil.getId(clazz.getSimpleName(), String.valueOf(id));
            Object value = JpaUtil.getRepository(clazz.getName()).findOne(id);
            if (value == null) throw new RuntimeException(String.format("变量：%s 值 %s 系统中不存在", k, id));
            parameters.put(k, value);
        });
        return parameters;
    }


}
